home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Magazine / C_Tutorial / Part-4 / screen0.c < prev    next >
C/C++ Source or Header  |  1997-08-31  |  8KB  |  296 lines

  1. #include "clip.h"
  2.  
  3. #include<exec/libraries.h>
  4. #include<intuition/intuition.h>
  5. #include<utility/tagitem.h>
  6. #include<graphics/text.h>
  7. #include<graphics/rastport.h>
  8. #include<intuition/screens.h>
  9. #include<libraries/gadtools.h>
  10.  
  11. #include<string.h>
  12. #include<stdio.h>
  13.  
  14. #include<clib/exec_protos.h>
  15. #include<clib/graphics_protos.h>
  16. #include<clib/intuition_protos.h>
  17. #include<clib/gadtools_protos.h>
  18.  
  19. /* The library base global variables */
  20. /* (The different style of opening libraries requires these to be initialised to NULL) */
  21. struct Library* GfxBase = NULL;
  22. struct Library* IntuitionBase = NULL;
  23. struct Library* LayersBase = NULL;
  24. struct Library* GadToolsBase = NULL;
  25.  
  26. /* The global handle on the palette gadget */
  27. struct Gadget* palgad = NULL;
  28.  
  29. /* Need to give prototypes for our functions */
  30. void handleIDCMP(struct Window*);
  31. void setupWindow();
  32. void createWindow(struct Gadget*);
  33. int openLibs();
  34. void closeLibs();
  35.  
  36. /* Some constants for the size of the window */
  37. #define MYWIN_WIDTH        (400)
  38. #define MYWIN_HEIGHT    (200)
  39.  
  40. /* Some constants for the position and size of our gadget */
  41. #define MYBUT_LEFT        (10)
  42. #define MYBUT_TOP            (5)
  43. #define MYBUT_WIDTH        (80)
  44. #define MYBUT_HEIGHT    (12)
  45. #define MYBUT_TEXT        "Next Pen"
  46. #define MYBUT_ID            (0)
  47.  
  48. #define MYPAL_LEFT        (170)
  49. #define MYPAL_TOP            (2)
  50. #define MYPAL_WIDTH        (109)
  51. #define MYPAL_HEIGHT    (19)
  52. #define MYPAL_TEXT        "Colour:"
  53. #define MYPAL_ID            (1)
  54. #define MYPAL_DEPTH        (4)
  55.  
  56. /* The top gap required around the gadgets */
  57. #define MYTOPGAP      (30)
  58.  
  59. /* The initial pen colour */
  60. #define MYINITPEN            (1)
  61.  
  62. /* The start of the program */
  63. void main()
  64. {
  65.     /* Use a different style of opening libraries... */
  66.     if(openLibs())
  67.     {
  68.         /* Now do the real work */
  69.         setupWindow();
  70.     }
  71.     /* Matched call to close libraries */
  72.     closeLibs();
  73. }
  74.  
  75. /* Try to open all the libraries -- return TRUE on success */
  76. int openLibs()
  77. {
  78.     if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
  79.     {
  80.         printf("Error: could not open graphics.library\n");
  81.         return FALSE;
  82.     }
  83.     if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
  84.     {
  85.         printf("Error: could not open intuition.library\n");
  86.         return FALSE;
  87.     }
  88.     if((LayersBase = OpenLibrary("layers.library",37)) == NULL)
  89.     {
  90.         printf("Error: could not open layers.library\n");
  91.         return FALSE;
  92.     }
  93.     if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
  94.     {
  95.         printf("Error: could not open gadtools.library\n");
  96.         return FALSE;
  97.     }
  98.   return TRUE;
  99. }
  100.  
  101. /* Close any open library */
  102. void closeLibs()
  103. {
  104.     if(GadToolsBase)
  105.         CloseLibrary(GadToolsBase);
  106.     if(LayersBase)
  107.         CloseLibrary(LayersBase);
  108.     if(IntuitionBase)
  109.         CloseLibrary(IntuitionBase);
  110.     if(GfxBase)
  111.         CloseLibrary(GfxBase);
  112. }
  113.  
  114. /* Setup the window -- do the GadTools stuff */
  115. void setupWindow()
  116. {
  117.     struct Screen* scr;
  118.     /* We'll copy the visual information for the default public screen */
  119.   /* (usually, this is the Workbench screen) */
  120.     if(scr = LockPubScreen(NULL))
  121.     {
  122.         APTR vinfo;
  123.         /* Get the visual info so GadTools can render the gadgets nicely */
  124.         if(vinfo = GetVisualInfo(scr, TAG_DONE))
  125.         {
  126.             /* We can initialise glist in its declaration */
  127.             struct Gadget* glist = NULL;
  128.             struct Gadget* gad;
  129.             int offtop, offleft;
  130.             struct NewGadget newgad;
  131.             /* Initialised structure declaration: describes 8pt Topaz font */
  132.             struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
  133.             /* Start a GadTools gadget list */
  134.             gad = CreateContext(&glist);
  135.             /* The offsets of our window borders */
  136.             offleft = scr->WBorLeft;
  137.             offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
  138.  
  139.             /* Setup our first gadget */
  140.             newgad.ng_TextAttr         = &topazFont;
  141.             newgad.ng_VisualInfo     = vinfo;
  142.             newgad.ng_LeftEdge         = MYBUT_LEFT + offleft;
  143.             newgad.ng_TopEdge         = MYBUT_TOP + offtop;
  144.             newgad.ng_Width             = MYBUT_WIDTH;
  145.             newgad.ng_Height             = MYBUT_HEIGHT;
  146.             newgad.ng_GadgetText    = MYBUT_TEXT;
  147.             newgad.ng_GadgetID        = MYBUT_ID;
  148.             newgad.ng_Flags                = 0;
  149.             /* Now create it and add it to our list */
  150.             gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_END);
  151.  
  152.             /* Setup our second gadget */
  153.             /* (We can reuse newgad, and just change the different bits) */
  154.             newgad.ng_LeftEdge         = MYPAL_LEFT + offleft;
  155.             newgad.ng_TopEdge         = MYPAL_TOP + offtop;
  156.             newgad.ng_Width             = MYPAL_WIDTH;
  157.             newgad.ng_Height             = MYPAL_HEIGHT;
  158.             newgad.ng_GadgetText    = MYPAL_TEXT;
  159.             newgad.ng_GadgetID        = MYPAL_ID;
  160.             newgad.ng_Flags                = 0;
  161.             /* Now create it and add it to our list */
  162.             if(gad = CreateGadget(PALETTE_KIND, gad, &newgad,
  163.                                                         /* Initially selected pen */
  164.                                                         GTPA_Color, MYINITPEN,
  165.                                                         /* Depth: 2 to the power MYPAL_DEPTH colours */
  166.                                                         GTPA_Depth, MYPAL_DEPTH,
  167.                                                         /* Gadget will indicate selection */
  168.                                                         GTPA_IndicatorWidth, 16,
  169.                                                         TAG_DONE))
  170.             {
  171.                 /* Remember gadget pointer so we can affect it in message handler */
  172.                 palgad = gad;
  173.                 /* If succeeded then all gadgets created */
  174.                 createWindow(glist);
  175.             }
  176.             else
  177.                 printf("Error: could not create gadget(s)\n");
  178.             /* Free all the gadgets that were created */
  179.             FreeGadgets(glist);
  180.             FreeVisualInfo(vinfo);
  181.         }
  182.         else
  183.             printf("Error: could not get visual info\n");
  184.         UnlockPubScreen(NULL, scr);
  185.     }
  186.     else
  187.         printf("Error: could not lock public screen\n");
  188. }
  189.  
  190. /* Actually open the window, in the normal way */
  191. void createWindow(struct Gadget* glist)
  192. {
  193.     struct Window* win;
  194.     /* Open our window */
  195.     if(win = OpenWindowTags(NULL,
  196.                                                     WA_Width,        MYWIN_WIDTH,
  197.                                                     WA_Height,    MYWIN_HEIGHT,
  198.                                                     WA_Flags,        WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_REPORTMOUSE,
  199.                                                     WA_IDCMP,        IDCMP_CLOSEWINDOW | IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | BUTTONIDCMP | IDCMP_REFRESHWINDOW,
  200.                                                     WA_Gadgets,    glist,
  201.                                                     TAG_DONE,        0))
  202.     {
  203.         /* If window opened, set clip region */
  204.         if(setClipInternal(win))
  205.         {
  206.             /* Let GadTools refresh its bits of the window */
  207.             GT_RefreshWindow(win, NULL);
  208.             /* Now handle messages */
  209.             handleIDCMP(win);
  210.             removeClip(win);
  211.         }
  212.         else
  213.             printf("Error: could not set clip region on window\n");
  214.         CloseWindow(win);
  215.     }
  216.     else
  217.         printf("Error: could not open window\n");
  218. }
  219.  
  220. /* Our message handling code */
  221. void handleIDCMP(struct Window* win)
  222. {
  223.     char* text = "Hello World!";
  224.     int going = TRUE;
  225.     int drawing = FALSE;
  226.     UBYTE pen = MYINITPEN;
  227.     SetAPen(win->RPort, pen);
  228.     /* Set the drawing mode to draw only the foreground of text, not the background */
  229.     SetDrMd(win->RPort, JAM1);
  230.     while(going)
  231.     {
  232.         struct IntuiMessage* intuimsg;
  233.         /* Wait for messages to arrive */
  234.         WaitPort(win->UserPort);
  235.         /* Messages have arrived: loop through all of them */
  236.         while(intuimsg = GT_GetIMsg(win->UserPort))
  237.         {
  238.             /* Act on this message... */
  239.             switch(intuimsg->Class)
  240.             {
  241.             case IDCMP_MOUSEBUTTONS:
  242.                 switch(intuimsg->Code)
  243.                 {
  244.                 case SELECTDOWN:
  245.                     drawing = TRUE;
  246.                     break;
  247.                 case SELECTUP:
  248.                     drawing = FALSE;
  249.                     break;
  250.                 }
  251.                 /* break; omitted so we draw on click, too */
  252.             case IDCMP_MOUSEMOVE:
  253.                 /* Don't draw on top gap which holds gadgets */
  254.                 if(drawing && intuimsg->MouseY > win->BorderTop+MYTOPGAP)
  255.                 {
  256.                     Move(win->RPort, intuimsg->MouseX, intuimsg->MouseY);
  257.                     Text(win->RPort, text, strlen(text));
  258.                 }
  259.                 break;
  260.             case IDCMP_CLOSEWINDOW:
  261.                 going = FALSE;
  262.                 break;
  263.             case IDCMP_REFRESHWINDOW:
  264.                 /* You *MUST* remember to ask for and handle these refresh messages */
  265.                 GT_BeginRefresh(win);
  266.                 GT_EndRefresh(win, TRUE);
  267.                 break;
  268.             case IDCMP_GADGETUP:
  269.                 /* Trick: introduce new "{..}" scope so we can declare gad locally */
  270.                 {
  271.                     struct Gadget* gad = (struct Gadget*)(intuimsg->IAddress);
  272.                     switch(gad->GadgetID)
  273.                     {
  274.                     case MYBUT_ID:
  275.                         /* Our button was clicked!  Set foreground to next pen colour */
  276.                         /* (Wrap when reached the end of the palette gadget's colours) */
  277.                         pen = (pen+1) % (1<<MYPAL_DEPTH);
  278.                         SetAPen(win->RPort, pen);
  279.                         /* Update palette gadget with new pen value */
  280.                         GT_SetGadgetAttrs(palgad, win, NULL, GTPA_Color, pen, TAG_DONE);
  281.                         break;
  282.                     case MYPAL_ID:
  283.                         /* Our palette gadget was clicked!  Set foreground to gadget colour */
  284.                         pen = intuimsg->Code;
  285.                         SetAPen(win->RPort, pen);
  286.                         break;
  287.                     }
  288.                     break;
  289.                 }
  290.             }
  291.             /* Reply when finished with message */
  292.             GT_ReplyIMsg(intuimsg);
  293.         }
  294.     }
  295. }
  296.